use crate::{constants::{MI_PADDING_SIZE, MI_PAGES_DIRECT, MI_SMALL_SIZE_MAX}, init::_mi_heap_empty, types::{MiHeap, MiPage}};


// Is `x` a power of two? (0 is considered a power of two)
pub fn _mi_is_power_of_two(x: usize) -> bool {
    (x & (x - 1)) == 0
}

// Align a byte size to a size in _machine words_,
// i.e. byte size == `wsize*sizeof(void*)`.
pub fn _mi_wsize_from_size(size: usize) -> usize {
    assert!(size <= usize::MAX - size_of::<usize>());
    return (size + size_of::<usize>() - 1) / size_of::<usize>();
}

pub unsafe fn mi_page_block_size(page: *mut MiPage) -> usize {
    assert!((*page).block_size > 0);
    (*page).block_size
}

/*----------------------------------------------------------------------------------------
  Heap functions
------------------------------------------------------------------------------------------- */


pub unsafe fn mi_heap_is_backing(heap: *const MiHeap) -> bool {
    (*(*heap).tld).heap_backing as *const MiHeap == heap
}

pub fn mi_heap_is_initialized(heap: *const MiHeap) -> bool {
    assert!(!heap.is_null());
    heap != &_mi_heap_empty
}


/* -----------------------------------------------------------
  Pages
----------------------------------------------------------- */

pub unsafe  fn _mi_heap_get_free_small_page(heap: *mut MiHeap, size: usize) -> *mut MiPage {
    assert!(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE));
    let idx: usize = _mi_wsize_from_size(size);
    assert!(idx < MI_PAGES_DIRECT);
    (*heap).pages_free_direct[idx]
    
}